#include <iostream>
#include <memory>
#include <string>


// 1.简单工厂模式
class Fruit{
public:
    // = 0 声明为纯虚函数 在当前基类中没有实现 交给派生类实现
    // 类里面有至少有一个纯虚函数 当前类就是“抽象类” 不能直接实例化
    virtual void name() = 0;
};

class Apple : public Fruit {
public:
    void name() override {
        std::cout << "I am a apple..." << std::endl;
    } 
};

class Banana : public Fruit {
public:
    void name() override {
        std::cout << "I am a banana..." << std::endl;
    }
};
// class FruitFactory{
// public:
//     // Fruit基类的引用或指针指向派生类对象（向上转型）
//     static std::shared_ptr<Fruit> create(const std::string &name){
//         if(name == "Apple"){
//             // std::make_shared创建对象 并返回shared_ptr
//             return std::make_shared<Apple>();
//         }
//         else{
//             return std::make_shared<Banana>();
//         }
//     }
// };


// 2.工厂方法实现 核心思想：一个产品对应一个工厂
// class FruitFactory{
// public:
//     virtual std::shared_ptr<Fruit> create() = 0;
// };

// class AppleFactory : public FruitFactory{
// public:
//     std::shared_ptr<Fruit> create() override{
//         return std::make_shared<Apple>();
//     }
// };

// class BananaFactory : public FruitFactory{
// public:
//     std::shared_ptr<Fruit> create()override{
//         return std::make_shared<Banana>();
//     }
// };


// 3.抽象工厂模式
class Animal{
public:
    virtual void name() = 0;
};

class Dog : public Animal{
public:
    void name() override{
        std::cout << "I am a Dog..." << std::endl;
    }
};

class Pig : public Animal{
public:
    void name() override {
        std::cout << "I am a Pig..." << std::endl;
    }
};
// 超级工厂——抽象类
class Factory{
public:
    virtual std::shared_ptr<Animal> GetAnimal(const std::string &name) = 0;
    virtual std::shared_ptr<Fruit> GetFruit(const std::string &name) = 0;
};

class AnimalFactory : public Factory{
public:
    std::shared_ptr<Animal> GetAnimal(const std::string &name) override{
        if(name == "Dog"){
            return std::make_shared<Dog>();
        }
        else{
            return std::make_shared<Pig>();
        }
    }
private:
    std::shared_ptr<Fruit> GetFruit(const std::string &name) override{
        return nullptr;
    }
};

class FruitFactory : public Factory{
public:
    std::shared_ptr<Fruit> GetFruit(const std::string &name) override{
        if (name == "Apple"){
            return std::make_shared<Apple>();
        }
        else{
            return std::make_shared<Banana>();
        }
    }
private:
    std::shared_ptr<Animal> GetAnimal(const std::string &name) override{
        return nullptr;
    }
};
// 负责生产工厂的接口
class FactoryProduct{
public:
    static std::shared_ptr<Factory> create(const std::string &name){
        if(name == "Fruit"){
            return std::make_shared<FruitFactory>();
        }
        else{
            return std::make_shared<AnimalFactory>();
        }
    }
};

int
main()
{
    // std::shared_ptr<Fruit> fruit = FruitFactory::create("Apple");
    // fruit->name();
    // fruit = FruitFactory::create("Banana");
    // fruit->name();

    // std::shared_ptr<FruitFactory> ff(new AppleFactory);
    // std::shared_ptr<Fruit> fruit = ff->create();
    // fruit->name();
    // ff.reset(new BananaFactory);
    // fruit = ff->create();
    // fruit->name();

    std::shared_ptr<Factory> ff = FactoryProduct::create("Fruit");
    std::shared_ptr<Fruit> fruit = ff->GetFruit("Apple");
    fruit->name();
    fruit = ff->GetFruit("Banana");
    fruit->name();

    std::shared_ptr<Factory> af = FactoryProduct::create("Animal");
    std::shared_ptr<Animal> animal = af->GetAnimal("Dog");
    animal->name();
    animal = af->GetAnimal("Pig");
    animal->name();

    return 0;
}
